using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Services;

namespace Sudoku.Menu
{
	public enum ButtonState
	{
		NORMAL,
		DOWN,
	}
	
	public class Button : ExtendedGameComponent
	{
		protected ButtonState state;
		protected Rectangle rect;
		protected Texture2D texture;
		protected Boolean isToggle;
		protected Boolean isToggleDown;
		protected Boolean touchedIn;
		protected Color disabledColor;
		protected Color downColor;

		public delegate void ButtonEvent(Button sender);
		public event ButtonEvent OnHold;
		public event ButtonEvent OnTap;

		public Button(Game game, Rectangle r)
			: base(game)
		{
			rect = r;
			state = ButtonState.NORMAL;

			isToggleDown = false;
			Enabled = true;
			touchedIn = false;

			var inputService = game.Services.GetService(typeof(IInputManager)) as IInputManager;
			inputService.OnTouch += new InputManager.TouchEvent(OnTouch);
			inputService.OnTap += new InputManager.TouchEvent(OnTouchTap);
			inputService.OnMove += new InputManager.TouchEvent(OnTouchMove);

			disabledColor = Color.Black;
			disabledColor.A = 100;

			downColor = Color.Gray;
		}

		protected override void Dispose(bool disposing)
		{
			var inputService = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
			if (inputService != null)
			{
				inputService.OnTouch -= new InputManager.TouchEvent(OnTouch);
				inputService.OnTap -= new InputManager.TouchEvent(OnTouchTap);
				inputService.OnMove -= new InputManager.TouchEvent(OnTouchMove);
			}

			base.Dispose(disposing);
		}

		private void OnTouch(Vector2 touchPosition)
		{
			if (!Enabled) return;

			if (rect.Contains((int)touchPosition.X, (int)touchPosition.Y))
			{
				if (!isToggle)
				{
					state = ButtonState.DOWN;
				}

			}
		}

		private void OnTouchMove(Vector2 touchPosition)
		{
			if (!Enabled) return;

			if (rect.Contains((int)touchPosition.X, (int)touchPosition.Y))
			{
				Hold();
			}
			else if (!isToggle || !isToggleDown) state = ButtonState.NORMAL;
			
		}

		public void Hold()
		{
			if (!Enabled) return;

			if (state == ButtonState.NORMAL)
			{
				this.state = ButtonState.DOWN;
				if (OnHold != null) OnHold(this);
			}
		}

		private void OnTouchTap(Vector2 touchPosition)
		{
			if (!Enabled) return;

			if (rect.Contains((int)touchPosition.X, (int)touchPosition.Y))
			{
				Tap();
			}

		}

		public void Tap()
		{
			if (!Enabled) return;

			if (isToggle)
			{
				if (isToggleDown)
				{
					isToggleDown = false;
					state = ButtonState.NORMAL;
				}
				else
				{
					isToggleDown = true;
					state = ButtonState.DOWN;
				}
			}
			else
			{
				state = ButtonState.NORMAL;
			}

			if (OnTap != null) OnTap(this);
		}

		public override void Draw(GameTime gameTime)
		{
			base.Draw(gameTime);

			spriteBatch.Begin();

			switch (state)
			{
				case ButtonState.NORMAL:
					if (texture != null)				
						spriteBatch.Draw(texture, rect, Color.White);
					break;

				case ButtonState.DOWN:
					if (texture != null)				
						spriteBatch.Draw(texture, rect, downColor);
					break;
			}

			if (texture != null && !Enabled) spriteBatch.Draw(texture, rect, disabledColor);
			

			spriteBatch.End();
		}

		public Color DownColor
		{
			get { return downColor; }
			set { downColor = value; }
		}

		public Texture2D Texture
		{
			get { return texture; }
			set { texture = value; }
		}

		public Boolean IsToggle
		{
			get { return isToggle; }
			set { isToggle = value; }
		}

		public Boolean IsToggleDown
		{
			get { return isToggleDown; }
			set { isToggleDown = value; }
		}

		public ButtonState State
		{
			get { return state; }
			set 
			{
				state = value;
				if (state == ButtonState.NORMAL)
					isToggleDown = false;
			}
		}

		public Rectangle Position
		{
			get { return rect; }
		}

	}
}
